package com.stud.business.stud.controller;

import cn.afterturn.easypoi.excel.ExcelExportUtil;
import cn.afterturn.easypoi.excel.entity.TemplateExportParams;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.lock.LockInfo;
import com.baomidou.lock.LockTemplate;
import com.baomidou.lock.annotation.Lock4j;
import com.google.common.collect.Maps;
import com.stud.business.stud.domain.Stud;
import com.stud.common.constant.CacheConstants;
import com.stud.common.core.domain.Result;
import com.stud.common.core.domain.entity.SysDictData;
import com.stud.common.core.domain.entity.SysUser;
import com.stud.common.core.redis.RedisCache;
import com.stud.common.jdbc.MyJdbcTemplate;
import com.stud.common.utils.ListSplitUtil;
import com.stud.common.utils.PhoneMessageUtil;
import com.stud.common.utils.Toolkit;
import com.stud.common.utils.poi.EasyPoiUtil;
import com.stud.framework.web.service.SerialNoService;
import com.stud.system.domain.WorkflowLog;
import com.stud.system.service.SysDictDataService;
import com.stud.system.service.WorkflowLogService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import org.apache.commons.compress.utils.Lists;
import org.apache.poi.ss.usermodel.Workbook;
import org.redisson.api.RBlockingQueue;
import org.redisson.api.RedissonClient;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 测试
 *
 * @author Stud
 * @date 2022-11-28 18:55:35
 */
@Api(tags = "测试")
@RestController
@RequiredArgsConstructor
@RequestMapping("test")
public class TestController {

    private final MyJdbcTemplate jdbcTemplate;

    private final SerialNoService serialNoService;

    private final WorkflowLogService workflowLogService;

    private final SysDictDataService sysDictDataService;

    private final RedissonClient redissonClient;

    private final RedisCache redisCache;

    private final LockTemplate lockTemplate;

    @ApiOperation("插入数据测试")
    @PostMapping("/trimTest")
    public Result trimTest(@RequestBody String aaa, HttpServletRequest request) {
        return Result.ok("[" + aaa + "]");
    }

    @ApiOperation("发送短信测试")
    @GetMapping("/messageTest")
    public Result messageTest() {
        JSONObject params = new JSONObject();
        params.put("code", "6658");
        PhoneMessageUtil.send(params, "15205205173");
        return Result.ok();
    }

    @ApiOperation("excel根据模板导出")
    @GetMapping("/excelReportByModel")
    public void excelReportByModel(HttpServletResponse response, HttpServletRequest request) throws IOException {
        Map<String, Object> params = Maps.newHashMap();

        SysUser user = new SysUser();
        user.setUserName("吴彦祖");
        params.put("user", user);
        params.put("userName", "张学友");

        List<Object> list = Lists.newArrayList();

        for (int i = 1; i < 8; i++) {
            Map<String, Object> tempMap = Maps.newHashMap();
            tempMap.put("day", "星期" + i);
            list.add(tempMap);
        }

        params.put("list", list);

        TemplateExportParams templateExportParams = new TemplateExportParams("E:\\home\\stud\\template\\demo.xlsx");
        Workbook workbook = ExcelExportUtil.exportExcel(templateExportParams, params);
        EasyPoiUtil.downLoadExcel("demo.xlsx", response, request, workbook);

    }

    @ApiOperation("创建流水号")
    @GetMapping("/createSerialNo")
    public Result<String[]> createSerialNo(String businessCode, Integer total) {
        return Result.ok(serialNoService.create(businessCode, total));
    }

    @ApiOperation("字典新增条件测试")
    @GetMapping("/dictList")
    public Result<List<SysDictData>> dictList(String dictType, String[] dictValues) {
        return Result.ok(sysDictDataService.dictList(dictType, dictValues));
    }

    @ApiOperation("字典新增条件测试")
    @GetMapping("/updateFullById")
    public Result updateFullById() {
        WorkflowLog workflowLog = this.workflowLogService.getById(1L);
        workflowLog.setTaskName(null);
        //俩时间不生效,因为设置了fill
        workflowLog.setCreateTime(null);
        workflowLog.setUpdateTime(null);

        workflowLog.setCreateBy(null);
        workflowLog.setRoleName("哎呀");
        this.workflowLogService.updateFullById(workflowLog);
        return Result.ok();
    }

    @ApiOperation("redis队列测试")
    @GetMapping("/redisQueue")
    public Result redisQueue(Integer num) {
        RBlockingQueue<Integer> blockingQueue = redissonClient.getBlockingQueue(CacheConstants.DEVICE_ALERT_PW001);
        blockingQueue.expire(Duration.ofMinutes(30));
        blockingQueue.add(num);
        return Result.ok();
    }

    @ApiOperation("excel模版导出PDF,每一个sheet对应PDF一页")
    @GetMapping("/excelSheet2PDFPageDemo")
    public void excelSheet2PDFPageDemo(HttpServletRequest request, HttpServletResponse response) {
        System.out.println("excel模版导出PDF,每一个sheet对应PDF一页");
        List<Map> list = new ArrayList<>();
        for (int i = 0; i < 49; i++) {
            Map temp = new HashMap();
            temp.put("spare_name", "spare_name" + i);
            temp.put("model", "model" + i);
            temp.put("unit", "unit" + i);
            temp.put("serial_number", "serial_number" + i);
            temp.put("invoice_count", "invoice_count" + i);
            temp.put("change_count", "change_count" + i);
            temp.put("single_price", "single_price" + i);
            temp.put("change_amount", i);
            list.add(temp);
        }

        List<Map> otherParamList = new ArrayList<>();
        List<List<Map>> data = ListSplitUtil.spilt(list, 10);
        data.forEach(tempList -> {
            Map<String, String> otherParam = new HashMap<>();
            BigDecimal total = new BigDecimal("0");
            for (Map tempData : tempList) {
                total = Toolkit.bigDecimalAdd(total, tempData.get("change_amount"));
            }
            otherParam.put("total", Toolkit.formatNum(total, ""));
            otherParamList.add(otherParam);
        });

        Map<String, Object> paramsMap = new HashMap<>();
        paramsMap.put("date", DateUtil.today());
        paramsMap.put("project_name", "Stud测试项目");
        paramsMap.put("type", "类型1");
        paramsMap.put("fee_type", "类型2");

        EasyPoiUtil.exportExcelTemplate2PDF(
                "excelSheet2PDFPageDemo.xlsx", "excelSheet2PDFPageDemo.pdf", true, paramsMap, data, otherParamList, request, response);
    }

    @Lock4j(keys = {"#stud.id"}, acquireTimeout = 10000)
    @ApiOperation("redis锁测试")
    @GetMapping("/redisLock")
    public Result redisLock(Stud stud) {
        System.out.println(stud.getName() + "获得锁");
        try {
            Thread.sleep(5000L);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(stud.getName() + "执行完毕");
        return Result.ok();
    }

    /**
     * 行级锁要设计key
     *
     * @param stud
     * @return
     */
    @ApiOperation("lockTemplate锁测试")
    @GetMapping("/lockTemplateTest")
    public Result lockTemplateTest(Stud stud) {
        String key = "lock4j:stud.lockTemplateTest" + stud.getId();
        LockInfo lock = this.lockTemplate.lock(key, -1, 10000);
        System.out.println(stud.getName() + "获得锁");
        try {
            Thread.sleep(5000L);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        System.out.println(stud.getName() + "执行完毕");
        this.lockTemplate.releaseLock(lock);
        return Result.ok();
    }

}
